import { Context, Next } from 'koa';
import { AppContext, UserType, PermissionAction } from '@/types';
import User from '@/models/User.model';
import logger from '@/utils/logger';

/**
 * 超级管理员权限白名单
 * 超级管理员默认拥有所有权限
 */
const SUPER_ADMIN_PERMISSIONS = '*'; // * 表示所有权限

/**
 * 检查用户是否为超级管理员
 */
function isSuperAdmin(userType: UserType): boolean {
  return userType === UserType.SUPER_ADMIN;
}

/**
 * 权限检查中间件工厂函数
 */
export function requirePermission(resource: string, action: PermissionAction) {
  return async (ctx: Context, next: Next) => {
    const appCtx = ctx as AppContext;

    if (!appCtx.state.user) {
      ctx.throw(401, '未认证');
    }

    const { user } = appCtx.state;

    // ⭐ 超级管理员拥有所有权限，直接放行
    if (isSuperAdmin(user.type)) {
      logger.debug(
        `超级管理员访问: ${user.email} 执行 ${resource}:${action} [自动通过]`,
      );
      await next();
      return;
    }

    // 检查用户角色权限
    if (!user.roleId) {
      logger.warn(`用户 ${user.email} 未分配角色，拒绝访问 ${resource}:${action}`);
      ctx.throw(403, '用户未分配角色');
    }

    try {
      const userModel = await User.findByPk(user.id);

      if (!userModel || !userModel.roleId) {
        ctx.throw(403, '角色不存在');
      }

      const Role = (await import('@/models/Role.model')).default;
      const role = await Role.findByPk(userModel.roleId);
      
      if (!role) {
        ctx.throw(403, '角色不存在');
      }

      const hasPermission = await role.hasPermission(resource, action);

      if (!hasPermission) {
        logger.warn(
          `权限不足: 用户 ${user.email} 尝试执行 ${resource}:${action}`,
        );
        ctx.throw(403, '权限不足');
      }

      logger.debug(
        `权限检查通过: 用户 ${user.email} 可以执行 ${resource}:${action}`,
      );

      await next();
    } catch (error) {
      if (error instanceof Error && error.message.includes('权限')) {
        throw error;
      }
      logger.error('权限检查失败:', error);
      ctx.throw(500, '权限检查失败');
    }
  };
}

/**
 * 批量权限检查（需要满足其中一个权限即可）
 */
export function requireAnyPermission(permissions: Array<{ resource: string; action: PermissionAction }>) {
  return async (ctx: Context, next: Next) => {
    const appCtx = ctx as AppContext;

    if (!appCtx.state.user) {
      ctx.throw(401, '未认证');
    }

    const { user } = appCtx.state;

    // 超级管理员拥有所有权限
    if (isSuperAdmin(user.type)) {
      logger.debug(`超级管理员访问: ${user.email} [自动通过批量权限检查]`);
      await next();
      return;
    }

    if (!user.roleId) {
      ctx.throw(403, '用户未分配角色');
    }

    try {
      const userModel = await User.findByPk(user.id);

      if (!userModel || !userModel.roleId) {
        ctx.throw(403, '角色不存在');
      }

      const Role = (await import('@/models/Role.model')).default;
      const role = await Role.findByPk(userModel.roleId);
      
      if (!role) {
        ctx.throw(403, '角色不存在');
      }

      // 检查是否拥有任一权限
      let hasAnyPermission = false;
      for (const perm of permissions) {
        const has = await role.hasPermission(perm.resource, perm.action);
        if (has) {
          hasAnyPermission = true;
          break;
        }
      }

      if (!hasAnyPermission) {
        logger.warn(`权限不足: 用户 ${user.email} 没有所需的任何权限`);
        ctx.throw(403, '权限不足');
      }

      await next();
    } catch (error) {
      if (error instanceof Error && error.message.includes('权限')) {
        throw error;
      }
      logger.error('权限检查失败:', error);
      ctx.throw(500, '权限检查失败');
    }
  };
}

/**
 * 要求超级管理员权限
 */
export async function requireSuperAdmin(ctx: Context, next: Next) {
  const appCtx = ctx as AppContext;

  if (!appCtx.state.user) {
    ctx.throw(401, '未认证');
  }

  if (!isSuperAdmin(appCtx.state.user.type)) {
    logger.warn(`非超级管理员尝试访问: ${appCtx.state.user.email}`);
    ctx.throw(403, '需要超级管理员权限');
  }

  logger.debug(`超级管理员访问: ${appCtx.state.user.email}`);
  await next();
}

/**
 * 要求租户管理员权限（超级管理员也可以访问）
 */
export async function requireTenantAdmin(ctx: Context, next: Next) {
  const appCtx = ctx as AppContext;

  if (!appCtx.state.user) {
    ctx.throw(401, '未认证');
  }

  const { user } = appCtx.state;

  // 超级管理员或租户管理员都可以访问
  if (
    user.type !== UserType.SUPER_ADMIN &&
    user.type !== UserType.TENANT_ADMIN
  ) {
    logger.warn(`非租户管理员尝试访问: ${user.email}`);
    ctx.throw(403, '需要租户管理员权限');
  }

  logger.debug(`管理员访问: ${user.email} (${user.type})`);
  await next();
}

/**
 * 获取用户所有权限列表
 * 超级管理员返回所有权限
 */
export async function getUserPermissions(userId: string): Promise<string[]> {
  const user = await User.findByPk(userId);

  if (!user) {
    return [];
  }

  // 超级管理员拥有所有权限
  if (isSuperAdmin(user.type as any)) {
    return [SUPER_ADMIN_PERMISSIONS];
  }

  // 普通用户返回其角色的权限
  if (!user.roleId) {
    return [];
  }

  const Permission = (await import('@/models/Permission.model')).default;
  const RolePermission = (await import('@/models/RolePermission.model')).default;
  
  const rolePermissions = await RolePermission.findAll({
    where: { roleId: user.roleId },
  });
  
  const permissionIds = rolePermissions.map((rp: any) => rp.permissionId);
  const permissions = await Permission.findAll({
    where: { id: permissionIds },
  });

  return permissions.map((perm: any) => `${perm.resource}:${perm.action}`);
}

